﻿#pragma once

#include <ctime>
#include <functional>
#include <any>

//
// NOTICE 暂时禁用，暂时不开放给用户使用
//

namespace kratos {
namespace service {

class CoroRunner;

/**
 * 协程函数.
 */
using CoFunction = std::function<void(void)>;

/**
 * 协程ID.
 */
using COID = std::uint64_t;

/**
 * \brief 协程运行器
 * 
 * 提供一个协程管理器,封装了协程的操作方法,保证在组件关闭时自动关闭所有协程并释放协程资源
 */
class CoroRunner {
public:
  virtual ~CoroRunner() {}
  /**
   * 运行一个协程
   *
   * \param func 协程函数
   */
  virtual auto start_co(CoFunction func) -> COID = 0;
  /**
   * 睡眠当前协程
   *
   * \param ms 睡眠时间，毫秒
   */
  virtual auto sleep_co(std::time_t ms) -> void = 0;
  /**
   * 获取当前协程ID.
   * 
   * \return 
   */
  virtual auto get_id()->COID = 0;
  /**
   * 出让CPU.
   *
   * \return
   */
  virtual auto yield_co() -> void = 0;
  /**
   * 唤醒协程.
   * 
   * \param coid 协程ID
   */
  virtual auto resume_co(COID coid) -> void = 0;
  /**
   * 尝试获取数据,如果没有则立刻返回.
   * 
   * \return 数据
   */
  virtual auto try_co()->std::any = 0;
  /**
   *  一直阻塞等待数据到来.
   * 
   * \return 数据
   */
  virtual auto wait_co()->std::any = 0;
  /**
   * 一直阻塞一段时间等待数据到来.
   * 
   * \param timeout 超时时间，毫秒
   * \return 数据
   */
  virtual auto wait_co(std::time_t timeout)->std::any = 0;
  /**
   * 不能在非协程环境调用，启动一个协程等待执行完成，最多等待timeout毫秒，如果未完成则取消协程的执行.
   * 
   * \param timeout
   * \param func
   * \return 
   */
  virtual auto await_cancel_co(std::time_t timeout, CoFunction func)->bool = 0;
  /**
   * 发送数据给目标协程.
   * 
   * \param coid 协程ID
   * \param data 数据
   * \return true或false
   */
  virtual auto push_co(COID coid, std::any& data)->bool = 0;
  /**
   * 取消协程执行,协程栈上对象都会保证被正确析构.
   * 
   * \param coid 协程ID
   * \return 
   */
  virtual auto cancel_co(COID coid) -> void = 0;
  /**
   * 强制所有协程退出，处于挂起状态的所有协程都会退出，协程栈上对象都会保证被正确析构
   */
  virtual auto stop_all_co() -> void = 0;
};
} // namespace service
} // namespace kratos
